#ifndef GAMEENGINE_GRAPHICS_CAMERA_CAMERA_H
#define GAMEENGINE_GRAPHICS_CAMERA_CAMERA_H

#include <GameEngine/Graphics/graphics_settings.h>

#include <GameEngine/Geometry/Location/point3d.h>
#include <GameEngine/Geometry/Location/vector3d.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif


//! A camera sets up the modelview matrix so that the view seems to be fom the eye to the object
/*!
 *  A camera defines a specific point of view, from the observer (the "eye") to the object it
 *  observes (the "target"). To orientate the view along the axis eye-target, the upward direction
 *  also has to be specified (this orientation typically corresponds to the gravity vector,
 *  although other orientations are also totally acceptable). A zoom factor also allows to magnify
 *  or diminish the apparent distance to the target point (a zoom of 1 being the neutral factor).
 *
 *  The point of view is applied to the elements to be drawn by calling the apply_camera() function.
 */
class _Graphics_decl Camera {

public:
	Camera();
	Camera(const Camera& rhs);
	Camera& operator=(const Camera& rhs);
	virtual ~Camera();

	const Point3d<float>& eye() const;
	Point3d<float>& eye();
	const Point3d<float>& target() const;
	Point3d<float>& target();
	const Vector3d<float>& up() const;
	Vector3d<float>& up();
	float zoom() const;
	float& zoom();

	void apply_camera() const;

private:
	//! Location of the observer
	GAMEENGINE_DLL_CLASS(Point3d<float>) eye_;

	//! Location at which the observer is looking (reference point)
	GAMEENGINE_DLL_CLASS(Point3d<float>) target_;

	//! "Up" vector relatively to the observer
	GAMEENGINE_DLL_CLASS(Vector3d<float>) up_;

	//! Zoom factor
	float zoom_;
};


#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#endif
